package drp.snowbell.storage;

import java.util.Collection;
import java.util.List;
import java.util.Map;

import drp.snowbell.entity.IEntity;
import drp.snowbell.entity.Property;
import drp.snowbell.storage.filter.IFilter;


/**
 * 数据库存储器.
 * 
 * 存储器必须定义只有一个参数为String型EntityName的构造函数,EntityName为模块名称. 注意:
 * 1.不允许修改和删除字段,只能增加数据库字段
 * 2.查询的Filter不允许OR运算,只能AND,如果对同一个字段OR运算可以使用IN替代,不同的字段则只能用2次查询合并数据
 * 
 * @author woj
 * 
 */
public interface IStorage<E extends IEntity> {

	/**
	 * 获取存储器所属的模块的名称
	 * 
	 * @return 实体的名称
	 */
	String getEntityName();

	/**
	 * 从指定的Id加载
	 * 
	 * @param Id
	 *            TBean的Id
	 * @return 实体
	 */
	E load(String Id);

	/**
	 * 从指定的属性加载,该属性必须unique为true
	 * 
	 * @param prop
	 *            属性
	 * @param value
	 *            属性值
	 * @return 模块
	 */
	E loadWithProp(Property prop, Object value);

	/**
	 * 系统初始安装的时候调用,主要用于创建初始数据
	 */
	void install();

	/**
	 * 增加数据库表字段.
	 * 
	 * @param propList
	 */
	void addFileds(Collection<Property> propList);

	// /**
	// * 修改数据库字段.
	// *
	// * @param propList
	// */
	// void modifyFiled(Property prop);
	//
	// /**
	// * 删除字段.
	// *
	// * @param propList
	// */
	// void deleteFiled(Property prop);

	/**
	 * 删除一个实体记录
	 * 
	 * @param beanId
	 *            要删除的实体记录ID
	 */
	boolean delete(String entityId);

	/**
	 * 保存
	 * 
	 * @return 返回绑定的实体的Id值,更新失败返回null
	 */
	String save(E entry);

	/**
	 * 获取列表并分页
	 * 
	 * @param filterList
	 *            过滤条件列表,如果过滤条件为null或者空则返回所有数据.
	 * @param context
	 *            分页上下文,如果为null的话不分页.
	 * @return 模块列表,
	 *         非null值,使用List接口而不用Collection,是因为List可以获取指定索引的数据,而Collection不能,
	 *         虽然Collection占用资源少.
	 */
	List<E> getList(Collection<IFilter> filterList, PagingContext context);

	/**
	 * 获取所有的列表
	 * 
	 * @param exp
	 *            过滤条件表达式,如果过滤条件为null则返回所有数据.
	 * @return 
	 *         模块列表,非null值,使用List接口而不用Collection,是因为List可以获取指定索引的数据,而Collection不能
	 *         , 虽然Collection占用资源少.
	 */
	List<E> getList(Collection<IFilter> filterList);

	/**
	 * 全文搜索
	 * 
	 * @param keywordsMap
	 *            属性-关键字对应表.Map的key为要搜索的属性,value为关键字
	 * @param context
	 *            分页上下文
	 * @return
	 */
	List<E> searchFullText(Map<String, String> keywordsMap, PagingContext context);

	/**
	 * 全文搜索
	 * 
	 * @param keyword
	 *            查询的关键字
	 * @param context
	 *            分页上下文
	 * @return
	 */
	List<E> searchFullText(String keyword, PagingContext context);

	/**
	 * 获取所有的数据
	 * 
	 * @return
	 */
	List<E> getList();

	/**
	 * 批量更新,要更新的属性不允许有关联.否则抛异常
	 * 
	 * @param changeList
	 *            要更新的数据.Map的Key为要更新的属性,value为要更新的值.更新的属性必须为数据库字段(isDbField为
	 *            true)
	 * @param where
	 *            更新的数据的条件
	 * @return 更新的数据条数
	 */
	int batchUpdate(Map<Property, Object> changeList, Collection<IFilter> filterList);

	/**
	 * 批量删除
	 * 
	 * @param where
	 *            删除的条件
	 * @return 更新的数据条数
	 */
	int batchDelete(Collection<IFilter> filterList);

	/**
	 * 工厂方法新建一个实例,这样比反射创建效率高.
	 * 
	 * @return 新的实例
	 */
	IStorage<E> newInstance();

	/**
	 * 获取当前线程的事务;
	 * 
	 * @return 事务对象
	 */
	ITransaction getCurrentTransaction();
}
